package cz.worktracker.controller;

import cz.worktracker.enums.DataSetsEnum;
import cz.worktracker.model.entities.User;

import java.io.IOException;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import java.security.Principal;
import java.io.Serializable;
import java.util.logging.Level;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.inject.Named;
import org.hibernate.criterion.Order;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

/**
 * UserManager
 * Správa právě přihlášeného uživatele.
 * @since 2010-04-20
 * @author pagac, musil
 */
@ManagedBean
@SessionScoped
@Named
public class UserManager extends AbstractManager
                            implements Serializable {

    private static final long SerialVersionUID = 1L;
    
    private User user;
    private String username;

    /**
     * Constructor
     */
    public UserManager() { }

    @PostConstruct
    public void construct() {
        init();
    }

    @PreDestroy
    public void destroy() {
        user = null;
    }

    private void init() {
        getUser();
    }


    /**
     * Login
     * @throws IOException
     */
    public void login() throws IOException {
        // FacesContext.getCurrentInstance().getExternalContext().dispatch("j_security_check");
        getUser();
    }


    /**
     * Logout
     * @throws IOException
     */
    public void logout() throws IOException {
        FacesContext.getCurrentInstance().getExternalContext().log("logged out");
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        this.user = null;

        // FIXME Tohle bude dělat problém. Je třeba si nějak získat cestu ke kořenu webu.
        FacesContext.getCurrentInstance().getExternalContext().redirect(FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath());
    }


    /**
     * Zjištění stavu přihlášení uživatele.
     * @return true pokud je uživatel přihlášen, jinak false
     */
    public boolean isLoggedIn() {
        if( getUser() != null ) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * Získání dat uživatele, podle uživatelského jména
     * právě přihlášeného uživatele, z db.
     * @return User při úspěchu. null při neúspěchu.
     */
    public User getUser() {
        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();

         /* Už máme načteno. */
         if( user != null) {
            return user;
         }

         /* Zjistíme data o přihlášeném uživateli. */
         if(( user == null ) && ( principal != null )) {
             // from User where Login = 'pagac'
             this.username = principal.getName();

             if(getSession() == null) {
                 System.out.println("Session is null!");
             }

             Transaction tx = getSession().beginTransaction();
             String hql = "from User as user where user.login = '" + username + "'";
             Query query = getSession().createQuery (hql);
             query.setMaxResults(1);
             user = (User) query.uniqueResult();
             tx.commit();
             return user;
         }

        return null; /* Nepovedlo se získat data. */
    }


    /**
     * GetRole
     * @deprecated 
     * @return
     */
    public String getRole() {
        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();

        return FacesContext.getCurrentInstance().getExternalContext().isUserInRole("ADMIN") + " "
                    + FacesContext.getCurrentInstance().getExternalContext().isUserInRole("USER") + " "
                    + FacesContext.getCurrentInstance().getExternalContext().isUserInRole("NONE");
    }


    /**
     * Returns true if user has ADMIN role.
     * @return True if user is admin. Otherwise false.
     */
    public boolean isAdmin() {
        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();

        return FacesContext.getCurrentInstance().getExternalContext().isUserInRole("ADMIN");
    }


    /**
     * Updates user data.
     * @return String
     */
    public String update() {
        
        if (user != null) {
            try {
                Transaction tx = getSession().beginTransaction();
                getSession().update(user);
                user.setPassword(RegisterBean.MD5(user.getPassword()));
                tx.commit();
                init();
            } catch (Exception e) {
                getLogger(getClass()).log(Level.SEVERE, "Error on try to save User: ", e);
                addMessage("Error on try to save User");
                return null;
            }
        }
        
        return "main";
    }

}
